package system.service.sys.impl;

import framework.config.UserConfig;
import framework.defined.SystemDefined;
import framework.exceptions.BusinessException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import system.defined.FuncMoveType;
import system.entity.SysFunc;
import system.mapper.SysFuncMapper;
import system.service.sys.SysConfigService;
import system.service.sys.SysFuncService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class SysFuncServiceImpl implements SysFuncService {

    @Autowired
    @Getter
    private SysFuncMapper mapper;
    @Autowired
    private UserConfig userConfig;
    @Autowired
    private SysConfigService configService;
    @Autowired
    private CacheManager cacheManager;

    /**
     * 读取用户功能表
     *
     * @param userId
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<SysFunc> loadUserFunc(Long userId) {
        String cacheKey = "func_loadUserFunc_" + userId;
        List<SysFunc> f = new ArrayList<>();
        f = configService.getConfigOfVersion(cacheKey, f.getClass());
        if (f != null) return f;

        //管理员则直接返回全部权限
        if (this.userConfig.getSuperAdminId() != null
                && this.userConfig.getSuperAdminId() != 0L
                && this.userConfig.getSuperAdminId().equals(userId)
        ) {
            //load all permission
            log.warn("admin id " + userId + " load all func");
            //若是超级管理员，默认具有全部权限
            SysFunc query = new SysFunc();
            query.setIsDisabled(SystemDefined.NO_VALUE);
            f = this.mapper.load(query);
            //添加到配置项
            configService.setConfigOfVersion(cacheKey, f);
            return f;
        }

        //读取用户角色功能列表
        f = this.mapper.loadUserRoleFunc(userId);
        //读取岗位功能列表
        //funcList.addAll();

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, f);

        //
        return f;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<SysFunc> loadFuncAll() {
        String cacheKey = "func_loadFuncAll";
        List<SysFunc> f = new ArrayList<>();
        f = this.configService.getConfigOfVersion(cacheKey, f.getClass());
        if (f != null) return f;

        //
        f = this.getMapper().list(new SysFunc());

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, f);

        return f;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Map<String, List<SysFunc>> loadFuncAllMap() {
        String cacheKey = "func_loadFuncAllMap";
        Map<String, List<SysFunc>> m = new HashMap<>();
        m = this.configService.getConfigOfVersion(cacheKey, m.getClass());
        if (m != null) return m;

        //
        List<SysFunc> list = this.getMapper().list(new SysFunc());
        Map<String, List<SysFunc>> map = new HashMap<>();
        for (SysFunc f : list) {
            if (StringUtils.hasText(f.getFunPath())) {
                List<SysFunc> list2 = map.get(f.getFunPath());
                if (list2 == null) {
                    list2 = new ArrayList<>();
                    map.put(f.getFunPath(), list2);
                }
                list2.add(f);
            }
        }

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, map);

        //
        return map;
    }

    @Override
    public SysFunc loadFuncByRequest(String path, String method) {
        String cacheKey = "func_loadFuncByRequest_" + path + "_" + method;
        SysFunc func = this.configService.getConfigOfVersion(cacheKey, SysFunc.class);
        if (func != null) return func;

        //
        Map<String, List<SysFunc>> map = this.loadFuncAllMap();
        List<SysFunc> pathList = map.get(path);
        if (pathList != null) {
            for (SysFunc sysFunc : pathList) {
                if (StringUtils.hasText(sysFunc.getFunMethod())) {
                    if (method.equals(sysFunc.getFunMethod())) {
                        func = sysFunc;
                        break;
                    }
                } else {
                    func = sysFunc;
                    break;
                }
            }
        }

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, func);

        //
        return func;
    }

    @Override
    public Integer add(SysFunc param) {
        int rows = SysFuncService.super.add(param);
        //更新配置版本
        configService.updateConfigVersion();
        return rows;
    }

    @Override
    public Integer update(SysFunc param) {
        int rows = getMapper().update(param);
        //更新配置版本
        configService.updateConfigVersion();
        return rows;
    }

    /**
     * 删除功能及子功能
     *
     * @param id
     */
    @Override
    @Transactional
    public int deleteFunc(String id) {
        int counter = 0;
        SysFunc func = new SysFunc();
        func.setPid(id);
        List<SysFunc> parentList = mapper.list(func);
        for (SysFunc parentFunc : parentList) {
            counter += deleteFunc(parentFunc.getId());
        }
        counter += mapper.deleteByPrimaryKey(id);

        //更新配置版本
        configService.updateConfigVersion();

        return counter;
    }

    @Override
    public Integer deleteById(String id) {
        int rows = this.deleteFunc(id);
        //更新配置版本
        configService.updateConfigVersion();
        return rows;
    }

    /**
     * 移动节点位置
     *
     * @param id
     * @param targetId
     * @param moveType
     * @return
     */
    @Override
    @Transactional
    public int move(String id, String targetId, FuncMoveType moveType) {
        int rows = 0;

        SysFunc targetFunc = this.loadById(targetId);
        if (targetFunc == null)
            return rows;

        //
        String pid = targetFunc.getPid();
        Integer orderNum = targetFunc.getOrderNum();

        //目标对象
        SysFunc updateFunc = new SysFunc();
        updateFunc.setId(id);

        //更新目标所在级别排序号，使顺序正确
        if (FuncMoveType.AFTER.equals(moveType)) {
            rows += mapper.batchUpdateOrder(pid, orderNum, false);
            updateFunc.setOrderNum(orderNum);
            updateFunc.setPid(pid);
        } else if (FuncMoveType.BEFORE.equals(moveType)) {
            rows += mapper.batchUpdateOrder(pid, orderNum, true);
            updateFunc.setOrderNum(orderNum);
            updateFunc.setPid(pid);
        } else if (FuncMoveType.INNER.equals(moveType)) {
            //更新父级
            updateFunc.setPid(targetId);
        } else {
            throw new BusinessException("Not support FuncMoveType " + moveType.toString());
        }

        //update
        rows += this.update(updateFunc);

        //更新配置版本
        configService.updateConfigVersion();

        //受影响的行数
        return rows;
    }
}
